package com.qdlc.p2p.biz.service.lottery.impl;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;

import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import com.qdlc.p2p.biz.executer.ExecuterHelper;
import com.qdlc.p2p.biz.executer.impl.ScoreLotteryMoneyExecuter;
import com.qdlc.p2p.biz.log.score.BaseScoreLog;
import com.qdlc.p2p.biz.log.score.lottery.ScoreLotteryLog;
import com.qdlc.p2p.biz.log.score.lottery.ScoreLotteryWinningLog;
import com.qdlc.p2p.biz.service.lottery.AbstractLotteryService;
import com.qdlc.p2p.biz.service.lottery.LotteryMessageFactory;
import com.qdlc.p2p.biz.tpp.TppBaseInterface;
import com.qdlc.p2p.biz.tpp.TppServiceFactory;
import com.qdlc.p2p.biz.zdata.LotteryResult;
import com.qdlc.p2p.common.constant.Global;
import com.qdlc.p2p.common.constant.LotteryCategory;
import com.qdlc.p2p.common.exception.BusinessException;
import com.qdlc.p2p.common.exception.UserException;
import com.qdlc.p2p.common.util.DateUtil;
import com.qdlc.p2p.dal.common.SystemConfigHelper;
import com.qdlc.p2p.dal.common.SystemConfigHelper.Nid;
import com.qdlc.p2p.dal.dao.LotteryDao;
import com.qdlc.p2p.dal.dao.LotteryRecordDao;
import com.qdlc.p2p.dal.dao.ScoreDao;
import com.qdlc.p2p.dal.dao.ScoreLotteryRecordDao;
import com.qdlc.p2p.dal.dao.ScoreTypeDao;
import com.qdlc.p2p.dal.dto.Lottery;
import com.qdlc.p2p.dal.dto.LotteryRecord;
import com.qdlc.p2p.dal.dto.Score;
import com.qdlc.p2p.dal.dto.ScoreLotteryRecord;
import com.qdlc.p2p.dal.dto.Tpp;
import com.qdlc.p2p.dal.dto.User;
import com.qdlc.p2p.dal.model.ScoreLotteryModel;
import com.qdlc.p2p.dal.model.TppModel;
import com.qdlc.p2p.dal.util.SystemConfigs;

/**
 * 积分抽奖
 */
@Service("scoreDrawLotteryService")
public class ScoreDrawLotteryServiceImpl extends AbstractLotteryService {
    /** 积分抽奖 */
    private static final String SCORE_LOTTERY = "score_lottery";

    @Resource
    private ScoreDao scoreDao;

    @Resource
    private ScoreTypeDao scoreTypeDao;

    @Resource
    private LotteryDao lotteryDao;

    @Resource
    private ScoreLotteryRecordDao scoreLotteryRecordDao;

    @Resource
    private LotteryRecordDao lotteryRecordDao;

    @Override
    public Object process(User user, int category) {
        validation(user); // 可抽奖验证
        LotteryResult result = drawLottery(user, category); // 抽奖
        return useAndAward(user, result, getConsume()); // 花费 并 颁奖
    }

    @Override
    protected void validation(User user) {
        if (user == null) throw new UserException("用户不存在!", BusinessException.TYPE_JSON);
        Score userScore = scoreDao.findByUserId(user.getUserId());//获取积分信息
        int score = getConsume(); // 抽奖所需要积分
        if (userScore.getValidScore() < score) {
            throw new UserException("您当前可用积分不足!", BusinessException.TYPE_JSON);
        }
    }

    @Override
    protected void use(User user, int count) {
        // 不作处理
    }

    @Override
    public LotteryResult drawLottery(User user, int category) {
        List<Lottery> lotteryConfig = lotteryDao.getLotteryByCategory(category);
        if (lotteryConfig == null || lotteryConfig.isEmpty()) {
            throw new UserException("无法抽奖,请联系管理员！", BusinessException.TYPE_JSON);
        }

        // 保存概率列表
        int size = lotteryConfig.size();
        List<Double> orignalRates = new ArrayList<Double>(size);
        for (Lottery config : lotteryConfig) {
            orignalRates.add(config.getRate());
        }
        int index = drawLotteryAlgorithm(orignalRates);
        Lottery lottery = lotteryConfig.get(index);

        // 抽奖结果保存
        LotteryResult lotteryResult = new LotteryResult();
        BeanUtils.copyProperties(lottery, lotteryResult);

        //设置抽奖回复语并返回
        return LotteryMessageFactory.setMessage(lotteryResult);
    }

    /**
     * 消耗积分并颁奖
     *
     * @param user    抽奖用户
     * @param lottery 抽奖结果
     * @param score   抽奖分数
     */
    protected Object useAndAward(User user, LotteryResult lottery, int score) {
        //会员积分记录信息 更新积分， 更新日志信息
        Global.setTransfer("score", score);
        Global.setTransfer("name", lottery.getName());
        BaseScoreLog bLog = new ScoreLotteryLog(user.getUserId(), score);
        bLog.doEvent();
        if (lottery != null) {
            //积分抽奖记录表
            ScoreLotteryRecord scoreLotteryRecord = new ScoreLotteryRecord();
            scoreLotteryRecord.setUser(user);
            scoreLotteryRecord.setType(lottery.getType());
            scoreLotteryRecord.setValue(lottery.getValue());
            scoreLotteryRecord.setAddTime(DateUtil.getNow());
            scoreLotteryRecord.setAddIp(Global.getIP());
            scoreLotteryRecordDao.save(scoreLotteryRecord);
            //抽奖记录表
            LotteryRecord lotteryRecord = new LotteryRecord();
            BeanUtils.copyProperties(lottery, lotteryRecord);
            lotteryRecord.setCategory(LotteryCategory.SCORE.getCategory());
            lotteryRecord.setUserId(user.getUserId());
            lotteryRecord.setAddTime(DateUtil.getNow());
            lotteryRecordDao.save(lotteryRecord);

            if (lottery.getType() == ScoreLotteryModel.TYPE_SCORE) {
                //会员积分记录信息 更新积分， 更新日志信息
                Global.setTransfer("score", lottery.getValue());
                bLog = new ScoreLotteryWinningLog(user.getUserId(), (int) lottery.getValue());
                bLog.doEvent();
            } else if (lottery.getType() == ScoreLotteryModel.TYPE_MONEY) {
                //抽中现金
                double money = lottery.getValue();
                Global.setTransfer("money", money);
                Global.setTransfer("user", user);
                ScoreLotteryMoneyExecuter scoreLotteryMoneyExecuter = ExecuterHelper.getExecuter(ScoreLotteryMoneyExecuter.class);
                scoreLotteryMoneyExecuter.execute(money, user, new User(SystemConfigs.ADMIN_ID));

                Tpp tpp = new Tpp(TppModel.SCORE_LOTTERY_MONEY, TppModel.TPP_TRANSFER, null, user, money, null);
                tpp.setTppUserCustId(SystemConfigHelper.getValue(Nid.MERCHANT_ID));
                tpp.setTppBorrowId(TppModel.SCORE_LOTTERY_MONEY_NAME);
                TppModel tppModel = TppModel.instance(tpp);
                TppBaseInterface tppService = TppServiceFactory.newIntance();
                tppService.tppTransfer(tppModel);
            }
        }
        return lottery;
    }

    @Override
    protected Object award(User user, LotteryResult result) {
        return null;
    }

    @Override
    protected int getConsume() {
        return scoreTypeDao.getScoreTypeByNid(SCORE_LOTTERY).getValue(); // 抽奖所需要积分
    }

}
